package com.caiyigo.baihua.serviceImpl;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.caiyigo.baihua.dao.SystemResMapper;
import com.caiyigo.baihua.dao.SystemRoleMapper;
import com.caiyigo.baihua.dto.ResDto;
import com.caiyigo.baihua.dto.Result;
import com.caiyigo.baihua.dto.Tree;
import com.caiyigo.baihua.model.SystemRes;
import com.caiyigo.baihua.service.ResService;
import com.caiyigo.baihua.shiro.ShiroCache;
import com.caiyigo.baihua.shiro.ShiroExt;
import com.caiyigo.baihua.shiro.ShiroInterceptor;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;

@Transactional
@Service
public class ResServiceImpl implements ResService {
	@Autowired
	SystemResMapper resMapper;
	@Autowired
	SystemRoleMapper roleMapper;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.ResService#getTree(java.lang.Integer, int,
	 * java.lang.Integer)
	 */
	public List<Tree> getTree(Integer pid, int type, Integer passId) {
		// 根据用户角色来获取 列表
		List<Tree> trees = new ArrayList<Tree>();

		for (SystemRes res : getChild(pid, type)) {

			if (res.getId().equals(passId))
				continue;
			Tree tree = new Tree(res.getId(), res.getPid(), res.getName(),
					res.getIconCls(), res, false);
			tree.children = getTree(res.getId(), type, passId);
			if (tree.children.size() > 0)
				tree.changeState();

			trees.add(tree);
		}
		
		
		return trees;
	}

	public List<SystemRes> getChild(Integer id, Integer type) {
		ShiroExt ext = new ShiroExt();
		List<SystemRes> list = null;

		if (type == null)
			return resMapper.selectByPid(id);
		else if (id == null && type == TYPE_MEUE)
			list = resMapper.selectByTypeAndPidIsNull(type);
		else if (id == null && type == TYPE_PERMISSION)
			list = resMapper.selectByPidIsNull();
		else if (type == TYPE_MEUE)
			list = resMapper.selectByPidType(new SystemRes(id, type));
		else if (type == TYPE_PERMISSION)
			list = resMapper.selectByPid(id);

		// L.i(" child id ="+id +"list ="+list);

		if (id == null)
			return list;
		else if (TYPE_PERMISSION == type)
			return list;
		else {
			ListIterator<SystemRes> itor = list.listIterator();
			while (itor.hasNext()) {
				SystemRes r = itor.next();
				if (r.getUrl() == null)
					continue;
				if (!ext.hasPermission(r.getUrl())) {
					// L.i("remove "+r.getStr("url"));
					itor.remove();

				}
			}
		}

		return list;
	}

	/**
	 * type define
	 */
	public static int TYPE_MEUE = 1;
	public static final int TYPE_PERMISSION = 2;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.ResService#selectByPid(java.lang.Integer)
	 */
	@Override
	public List<SystemRes> selectByPid(Integer pid) {

		return resMapper.selectByPid(pid);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.ResService#selectByType(java.lang.Integer)
	 */
	@Override
	public List<SystemRes> selectByType(Integer type) {

		return resMapper.selectByType(type);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.ResService#selectByTypeAndPidIsNull(java.lang
	 * .Integer)
	 */
	@Override
	public List<SystemRes> selectByTypeAndPidIsNull(Integer type) {

		return resMapper.selectByTypeAndPidIsNull(type);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.ResService#selectByPidIsNull()
	 */
	@Override
	public List<SystemRes> selectByPidIsNull() {

		return resMapper.selectByPidIsNull();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.ResService#listBySeq()
	 */
	@Override
	public List<SystemRes> listBySeq() {

		return resMapper.listBySeq();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.ResService#selectByPidType(com.caiyigo.zoo.model
	 * .SystemRes)
	 */
	@Override
	public List<SystemRes> selectByPidType(SystemRes res) {

		return resMapper.selectByPidType(res);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.ResService#deleteByPrimaryKey(java.lang.Integer)
	 */
	@Override
	public int deleteByPrimaryKey(Integer id) {

		return 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.ResService#insert(com.caiyigo.zoo.model.SystemRes
	 * )
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	@Override
	public int insert(SystemRes record) {

		return resMapper.insert(record);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.ResService#insertSelective(com.caiyigo.zoo.model
	 * .SystemRes)
	 */
	@Override
	public int insertSelective(SystemRes record) {

		return resMapper.insert(record);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.ResService#selectByPrimaryKey(java.lang.Integer)
	 */
	@Override
	public SystemRes selectByPrimaryKey(Integer id) {

		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.ResService#updateByPrimaryKeySelective(com.caiyigo
	 * .zoo.model.SystemRes)
	 */
	@Override
	public int updateByPrimaryKeySelective(SystemRes record) {

		return resMapper.updateByPrimaryKeySelective(record);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.ResService#updateByPrimaryKey(com.caiyigo.zoo
	 * .model.SystemRes)
	 */
	@Override
	public int updateByPrimaryKey(SystemRes record) {

		return resMapper.updateByPrimaryKey(record);
	}

	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public int batchAdd(int roleId, String resIds) {
		List<ResDto> dtos = new ArrayList<ResDto>();
		String[] rosids = resIds.split(",");
		for (String string : rosids) {
			dtos.add(new ResDto(roleId, string));
		}
		return resMapper.batchAdd(dtos);

	}

	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public int add(SystemRes res) throws Exception {

		int result = resMapper.insert(res);
		if (result > 0)
			this.batchAdd(1, res.getId() + "");
		removeAuthorization();
		return result;

	}

	/***
	 * 删除自己的同时 删除 所有 子节点 属性名 必需为pid
	 * 
	 * @param para
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public boolean deleteByIdAndPid(Integer id) {
		int result = resMapper.deleteByPrimaryKey(id);

		List<SystemRes> list = resMapper.selectByPid(id);

		for (SystemRes m : list) {
			deleteByIdAndPid(m.getId());
			resMapper.deleteByPid(id);
			// Db.update("delete from " + tableName + " where pid=? ", id);
		}
		if (result >= 0) {
			removeAuthorization();
			return true;
		} else {
			return false;
		}

	}

	public boolean pidIsChild(Integer id, Integer pid) {
		boolean result = false;
		if (pid != null) {
			List<SystemRes> list = resMapper.selectByPid(id);

			if (list.size() == 0)
				result = false;

			for (SystemRes r : list) {
				if (pid.equals(r.getId())) {
					result = true;
					return result;
				} else {

					if (pidIsChild(r.getId(), pid)) {
						result = true;
						// L.i("result =" + result);
						return result;
					}
				}

			}
		}

		return result;

	}

	public Result edit(SystemRes res) {
		if (res.getId() == res.getPid())
			return new Result(false, "父节点不能为自己");
		else if (res.getType() == SystemRes.TYPE_PERMISSION
				&& this.getChild(res.getId(), null).size() > 0)
			return new Result(false, "功能属性不能有子节点");
		else if (this.pidIsChild(res.getId(), res.getPid()))
			return new Result(false, "父节点不能为子节点");
		else {
			if (this.updateByPrimaryKeySelective(res) >= 0) {
				removeAuthorization();
				return new Result(true);

			} else {
				return new Result(false);
			}

		}

	}

	private void removeAuthorization() {
		ShiroCache.clearAuthorizationInfoAll();
		ShiroInterceptor.updateUrls();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.ResService#getUrls()
	 */
	@Override
	public List<String> getUrls() {

		return resMapper.getUrls();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.ResService#getRes(int)
	 */
	@Override
	public List<SystemRes> getRes(int id) {

		return resMapper.getRes(id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.ResService#getResUrl(java.lang.String)
	 */
	@Override
	public List<String> getResUrl(String name) {
		// TODO Auto-generated method stub
		return resMapper.getResUrl(name);
	}
}
